﻿using Xejen.Communication.Http.Configuration;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace Xejen.Communication.Http.Abstract
{
    /// <summary>
    /// 表示http请求提供器
    /// <para>
    /// WebRequest/WebResponse：早期的网络请求一般使用HttpWebRequest/HttpWebResponse来处理
    /// </para>
    /// <para>
    /// WebClient：它对HttpWebRequest/HttpWebResponse进行了一些封装，使得用起来简易些，牺牲了点点性能
    /// </para>
    /// <para>
    /// HttpClient：它弥补了互联网发达后原先的HttpWebRequest/HttpWebResponse所缺失的一些功能，HttpClient简易使用而又完善
    /// </para>
    /// <para>
    /// RestSharp：它提供了序列化/反序列化机制以及支持Token身份验证，这些功能是HttpClient所没有的，RestSharp以nuget包的形式提供
    /// </para>
    /// <para>
    /// ServiceStack：这些方式请自行了解和实现
    /// </para>
    /// <para>Flurl：这些方式请自行了解和实现</para>
    /// <para>DalSoft.RestClient：这些方式请自行了解和实现</para>
    /// </summary>
    /// <see langword="在C＃中使用RESTful API的几种好方法" href="https://blog.csdn.net/sD7O95O/article/details/105872244"/>
    /// <creator>marc</creator>
    public interface IHttpInvoker
    {
        /// <inheritdoc cref="Xejen.Communication.Http.Configuration.HttpConfig"/>
        HttpConfig Config { get; set; }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="uri">请求的url</param>
        /// <param name="timeout">超时时间，单位：毫秒</param>
        /// <param name="cancellationToken">是否取消的令牌</param>
        /// <example>
        /// var response = await _provider.DeleteAsync{ResponseDto{object}}(_server + "/admin/delete?classId=" + classId, null, headers: new NameValueCollection { { "X-Access-Token", _token } });
        /// </example>
        /// <returns></returns>
        Task<HttpResponse> DeleteAsync(string uri, int timeout, CancellationToken cancellationToken);
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="uri">请求url</param>
        /// <param name="timeout">超时时间，单位：毫秒</param>
        /// <param name="cancellationToken">是否取消的令牌</param>
        /// <example>
        /// await provider.GetAsync{object}("http://192.168.3.164:9010/api/model-mgt/models");
        /// </example>
        /// <returns></returns>
        Task<HttpResponse> GetAsync(string uri, int timeout, CancellationToken cancellationToken);
        /// <summary>
        /// 创建。以可序列化为json字符串的object:data对象传入
        /// </summary>
        /// <param name="uri">请求url</param>
        /// <param name="data">待提交的数据对象，通常是个模型model数据。会被封闭为json传输</param>
        /// <param name="timeout">超时时间，单位：毫秒</param>
        /// <param name="cancellationToken">是否取消的令牌</param>
        /// <example>
        /// await provider.PostAsync{object}("http://192.168.3.164:9010/api/model-mgt/models", new { ownerId = "abc", name = "才能当上" });
        /// 或者
        /// await _provider.PostAsync{ResponseDto{LoginDto}}(
        ///         _server + "admin/sys/login",
        ///         new
        ///         {
        ///             username = userName,
        ///             password = password,
        ///             skipCaptcha = true
        ///         },
        ///         headers: new NameValueCollection
        ///         {
        ///             { "x-company-code", "a234" }
        ///         });
        /// </example>
        /// <returns></returns>
        Task<HttpResponse> PostAsync(string uri, object data, int timeout, CancellationToken cancellationToken);
        ///// <summary>
        ///// 上传文件。服务端以IFileInfo的方式接收请求信息
        ///// </summary>
        ///// <param name="uri">请求url</param>
        ///// <param name="stream">待上传的文件字节流</param>
        ///// <param name="disposition">内容头信息</param>
        ///// <param name="cancellationToken">是否取消的令牌</param>
        ///// <returns></returns>
        //Task<HttpResponse> PostAsync(string uri, Stream stream, ContentDispositionHeaderValue disposition, int timeout , CancellationToken cancellationToken);
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="uri">请求的url</param>
        /// <param name="data">待提交的数据对象。会被封装为json传输</param>
        /// <param name="timeout">超时时间，单位：毫秒</param>
        /// <param name="cancellationToken">是否取消的令牌</param>
        /// <returns></returns>
        Task<HttpResponse> PutAsync(string uri, object data, int timeout, CancellationToken cancellationToken);
    }
}
